<script lang="ts" setup>
import { useRouter } from 'vue-router';

import { Buffer } from 'buffer';
import xlsx from 'node-xlsx';

import docxtemplater from 'docxtemplater';
import PizZip from 'pizzip';
import JSZipUtils from 'jszip-utils';
import { saveAs } from 'file-saver';

import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';
const router = useRouter();
const tableValue = reactive({
  unit: 'china',
  date: undefined,
  sampleType: '测试',
  people: '黄种人',
  name: '大伟',
  sex: '男',
  age: '35',
  card: '430123199001012345',
  work: '前端工程师',
  id: '',
  jiance: '技术提升',
  date2: undefined,
});
const exportWord = () => {
  let docxname = '导出word.docx';
  JSZipUtils.getBinaryContent('/template.docx', function (error: any, content: any) {
    // template.docx是模板（这里我放到public公共文件夹下面了）。我们在导出的时候，会根据此模板来导出对应的数据
    // 抛出异常
    if (error) {
      throw error;
    }

    // 创建一个PizZip实例，内容为模板的内容
    let zip = new PizZip(content);
    // 创建并加载docx templater实例对象
    let doc = new docxtemplater().loadZip(zip);
    // 设置模板变量的值  主要变量替换在这里
    doc.setData({
      name: tableValue.name,
      unit: tableValue.unit,
      date: '这里也不可以不写变量',
      sampleType: tableValue.sampleType,
      sex: tableValue.sex,
      age: tableValue.age,
      card: tableValue.card,
    });

    try {
      // 用模板变量的值替换所有模板变量
      doc.render();
    } catch (error: any) {
      // 抛出异常
      let e = {
        message: error.message,
        name: error.name,
        stack: error.stack,
        properties: error.properties,
      };
      console.log(
        JSON.stringify({
          error: e,
        }),
      );
      throw error;
    }

    // 生成一个代表docxtemplater对象的zip文件（不是一个真实的文件，而是在内存中的表示）
    let out = doc.getZip().generate({
      type: 'blob',
      mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    });
    // 将目标文件对象保存为目标类型的文件，并命名
    saveAs(out, docxname);
  });
};
const exportXlsx = () => {
  let data = [
    [1, 222, '', '', '', ''],
    ['', 2, 3, 4, 5, 6],
    ['', 2, 3, 4, 5, 6],
    ['', 2, 3, 4, 5, 6],
    ['', 2, 3, 4, 5, 6],
    [22, 2, 3, 4, 5, 6],
  ];

  // 行列合并规则  c：col 列   r:row 行
  const range0 = { s: { c: 0, r: 0 }, e: { c: 0, r: 4 } };
  const range1 = { s: { c: 1, r: 0 }, e: { c: 5, r: 0 } };
  const sheetOptions = {
    '!merges': [range0, range1],
    // cols 列宽大小
    '!cols': [{ wch: 5 }, { wch: 10 }, { wch: 15 }, { wch: 20 }, { wch: 30 }, { wch: 50 }],
  };
  //如果不需要格式，这里的sheetOptions可以省略不写
  let result = xlsx.build([{ name: 'sheet1', data }], { sheetOptions });
  // 两种方法都可以
  // const ab = Buffer.from(result, 'binary');
  const ab = new Uint8Array(result);
  const blob = new Blob([ab]);
  const blobUrl = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = blobUrl;
  a.download = '导出excel.xlsx';
  a.click();
  window.URL.revokeObjectURL(blobUrl);
};

const exportPdf = () => {
  downloadPDF(document.querySelector('#exportPdf'), '导出pdf文件', pdfSuc(), 4);
};
const pdfSuc = () => {
  message.success('导出成功');
};
/**
 * ele:需要导出的容器
 * pdfName：导出文件的名字
 * callback: 成功回调
 */
const downloadPDF = (ele: any, pdfName: any, callback: any, scale?: number) => {
  html2canvas(ele, {
    dpi: 600,
    scale: scale ? scale : 8,
    // allowTaint: true,  //允许 canvas 污染， allowTaint参数要去掉，否则是无法通过toDataURL导出canvas数据的
    useCORS: true, //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
    width: ele.scrollWidth,
    height: ele.scrollHeight,
  }).then((canvas) => {
    //未生成pdf的html页面高度
    var leftHeight = canvas.height;
    var a4Width = 595.28;
    var a4Height = 801.89; //（一张A4高=841.89减去20，使得上下边距空出20,pdf.addImage生成上边距（第四个参数=10）致使使得上下边距各10）
    //一页pdf显示html页面生成的canvas高度;
    var a4HeightRef = Math.floor((canvas.width / a4Width) * a4Height);
    //pdf页面偏移
    var position = 0;
    var pageData = canvas.toDataURL('image/jpeg', 1.0);
    var pdf = new JsPDF('x', 'pt', 'a4');
    var index = 1,
      canvas1 = document.createElement('canvas'),
      height;
    pdf.setDisplayMode('fullwidth', 'continuous', 'FullScreen');

    function createImpl(canvas) {
      if (leftHeight > 0) {
        index++;
        var checkCount = 0;
        if (leftHeight > a4HeightRef) {
          var i = position + a4HeightRef;
          for (i = position + a4HeightRef; i >= position; i--) {
            var isWrite = true;
            for (var j = 0; j < canvas.width; j++) {
              var c = canvas.getContext('2d').getImageData(j, i, 1, 1).data;
              if (c[0] != 0xff || c[1] != 0xff || c[2] != 0xff) {
                isWrite = false;
                break;
              }
            }
            if (isWrite) {
              checkCount++;
              if (checkCount >= 10) {
                break;
              }
            } else {
              checkCount = 0;
            }
          }
          height = Math.round(i - position) || Math.min(leftHeight, a4HeightRef);
          if (height <= 0) {
            height = a4HeightRef;
          }
        } else {
          height = leftHeight;
        }
        canvas1.width = canvas.width;
        canvas1.height = height;
        var ctx = canvas1.getContext('2d');
        ctx.drawImage(canvas, 0, position, canvas.width, height, 0, 0, canvas.width, height);
        if (position != 0) {
          pdf.addPage();
        }
        // 在pdf.addImage(pageData, 'JPEG', 左间距，上间距，宽度，高度)设置在pdf中显示；
        pdf.addImage(
          canvas1.toDataURL('image/jpeg', 1.0),
          'JPEG',
          70,
          56,
          a4Width - 140,
          (a4Width / canvas1.width) * height - 112,
        );

        leftHeight -= height;
        position += height;
        if (leftHeight > 0) {
          setTimeout(createImpl, 500, canvas);
          callback();
        } else {
          pdf.save(pdfName);
          callback();
        }
      }
    }

    // 当内容未超过pdf一页显示的范围，无需分页
    if (leftHeight < a4HeightRef) {
      pdf.addImage(pageData, 'JPEG', 0, 50, a4Width, (a4Width / canvas.width) * leftHeight);
      pdf.save(pdfName);
      // callback();
    } else {
      try {
        pdf.deletePage(0);
        setTimeout(createImpl, 500, canvas);
      } catch (err) {
        console.log(err);
      }
    }
  });
};
</script>

<template>
  <a-space>
    <a-button type="primary" @click="exportWord">导出word</a-button>
    <a-button type="primary" @click="exportXlsx">导出excel</a-button>
    <a-button type="primary" @click="exportPdf">导出pdf</a-button>
    <!-- <a-button type="primary" danger @click="() => router.push('/preview')"
        >nodemailer 发送邮箱</a-button
      > -->
    <a-button type="primary" danger @click="() => router.push('/preview')">文件预览</a-button>
    <a-button type="primary" danger @click="() => router.push('/common')">lanuage theme</a-button>
  </a-space>
</template>

<style lang="less" scoped></style>
